package com.jolink.omiis.wechat.redis;

import java.io.File;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.util.Pool;

public class RedisPoolFactory {

	private static final Logger logger = LoggerFactory.getLogger(RedisPoolFactory.class);

	private static RedisPoolFactory instance = null;

	private static JedisCluster jedisCluster;

	private static byte[] lock = new byte[] {};

	private RedisPoolFactory() {
		initialize();
		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
			public void run() {
				shutdown();
			}
		}));
	}

	/**
	 * jedis-pool实例对象
	 */
	private static Pool<Jedis> jedisPool = null;

	/**
	 * 初始化jedis-pool
	 */
	private void initialize() {
		// long t1 = System.currentTimeMillis();
		// logger.info("开始初始化Redis连接池......");
		// Properties prop = ConfigUtils.loadConfig(new
		// File(IPreferenceKeys.REDIS_CONFIG_PATH));
		// logger.info("Redis连接池配置信息：" + prop);
		// String redis_mode = prop.getProperty("mode", "standalone");
		// try {
		// if ("standalone".equals(redis_mode)) {
		// JedisPoolConfig config = new JedisPoolConfig();
		// String host = prop.getProperty("host");
		// String port = prop.getProperty("port", "6379");
		// String admin = prop.getProperty("admin");
		// config.setMaxIdle(Integer.parseInt(prop.getProperty("maxIdle",
		// "2")));
		// config.setMinIdle(Integer.parseInt(prop.getProperty("minIdle",
		// "1")));
		// config.setMaxTotal(Integer.parseInt(prop.getProperty("maxTotal",
		// "2")));
		// jedisPool = new JedisPool(config, host, Integer.parseInt(port), 1000
		// * 30, admin);
		// } else if ("cluster".equals(redis_mode)) {
		//
		// } else if ("sentinel".equals(redis_mode)) {
		// String sentinelAddress = prop.getProperty("sentinelAddress");
		// String masterName = prop.getProperty("masterName");
		// String admin = prop.getProperty("admin");
		// Set<String> sentinels = new
		// HashSet<>(Arrays.asList(sentinelAddress.split(",")));
		// jedisPool = new JedisSentinelPool(masterName, sentinels, admin);
		// }
		// } catch (Exception e) {
		// throw new RuntimeException(e.getMessage(), e);
		// }
		// long t2 = System.currentTimeMillis();
		// logger.info("初始化Reids连接池完成，耗时：" + (t2 - t1) + "毫秒。");
	}

	public static RedisPoolFactory getInstance() {
		if (instance == null) {
			synchronized (lock) {
				if (instance == null) {
					instance = new RedisPoolFactory();
				}
			}
		}
		return instance;
	}

	/**
	 * 从连接池获取jedis
	 * 
	 * @return
	 */
	public Jedis createJedisClient() {
		return jedisPool.getResource();
	}

	private void initJedisCluster() {
		long t1 = System.currentTimeMillis();
		logger.info("开始初始化JedisCluster......");
		Properties prop = ConfigUtils.loadConfig(new File(IPreferenceKeys.REDIS_CONFIG_PATH));
		logger.info("RedisCluster集群属性：{}。", prop);
		String clusterAddress = prop.getProperty("clusterAddress");
		String[] addressArray = clusterAddress.split(",");
		Set<HostAndPort> nodes = new HashSet<>();
		for (String addr : addressArray) {
			String[] splits = addr.split(":");
			HostAndPort hap = new HostAndPort(splits[0], Integer.parseInt(splits[1]));
			nodes.add(hap);
		}
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxIdle(100);
		poolConfig.setMinIdle(10);
		poolConfig.setTestOnBorrow(true);
		poolConfig.setTestOnReturn(true);
		poolConfig.setTestWhileIdle(true);
		int connectionTimeout = Integer.parseInt(prop.getProperty("connectionTimeout", "5000"));
		int soTimeout = Integer.parseInt(prop.getProperty("soTimeout", "5000"));
		int maxAttempts = Integer.parseInt(prop.getProperty("maxAttempts", "5"));
		String password = prop.getProperty("password", "jolink.15.9.18.net.cn");
		jedisCluster = new JedisCluster(nodes, connectionTimeout, soTimeout, maxAttempts, password, poolConfig);
		long t2 = System.currentTimeMillis();
		logger.info("初始化JedisCluster完成，耗时：{}毫秒。", (t2 - t1));
	}

	public JedisCluster createJedisCluster() {
		if (jedisCluster == null) {
			synchronized (RedisPoolFactory.class) {
				if (jedisCluster == null) {
					initJedisCluster();
				}
			}
		}

		return jedisCluster;
	}

	/**
	 * 释放jedis资源，jedis来自pool，用完需归还
	 * 
	 * @param jedis
	 */
	public void close(Jedis jedis) {
		if (jedis != null && jedis.isConnected()) {
			jedis.close();

		}
	}

	/**
	 * 关闭jedis连接池资源（通过Runtime注册Hook的方式关闭，不需要app显示关闭）
	 */
	public void shutdown() {
		// long t1 = System.currentTimeMillis();
		// logger.info("开始关闭Jedis连接池......");
		// jedisPool.close();
		// long t2 = System.currentTimeMillis();
		// logger.info("关闭Jedis连接池完成，耗时：{}毫秒。", (t2 - t1));
	}
}
